package sf.member.controller;

import java.text.ParseException;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import sf.core.controller.BaseController;
import sf.core.entity.TfMessage;
import sf.core.entity.TfOrder;
import sf.core.entity.TuMember;
import sf.core.exception.SugarException;
import sf.core.mapper.TfMessageMapper;
import sf.core.mapper.TfOrderMapper;
import sf.core.mapper.TuMemberMapper;
import sf.core.service.AuthService;
import sf.core.service.KeyValueService;
import sf.core.service.StorageService;
import sf.member.utils.CryptUtil;
import sf.member.vo.Messages;
import sf.member.vo.Order;
import sf.member.vo.Profile;
import sf.member.vo.Result;
import sf.member.vo.Token;
import sf.member.vo.Wallet;
import tk.mybatis.mapper.entity.Example;

/**
 * Created by ligen on 16-3-2.
 */

@RequestMapping("/me")
@RestController
public class MineController extends BaseController {

	@Resource
	TuMemberMapper memberMapper;

	@Resource
	KeyValueService keyValueService;

	@Resource
	TfOrderMapper orderMapper;

	@Resource
	AuthService<Integer> authService;

	@Resource
	StorageService storageService;

	@Resource
	TfMessageMapper messageMapper;

	@RequestMapping(value = "/profile", method = RequestMethod.GET)
	public Profile getProfile(HttpServletRequest request) throws SugarException {
		Integer uid = authService.getSubject(request);
		System.out.println(memberMapper.selectByPrimaryKey(uid));
		Optional<TuMember> opt = Optional.of(memberMapper.selectByPrimaryKey(uid));

		Profile profile = new Profile();
		profile.p2v(opt.get());
		return profile;
	}

	@RequestMapping(value = "/profile", method = RequestMethod.POST)
	public Profile setProfile(HttpServletRequest request, @RequestBody Profile profile)
			throws SugarException, ParseException {
		Integer uid = authService.getSubject(request);
		Optional<TuMember> opt = Optional.of(memberMapper.selectByPrimaryKey(uid));
		TuMember member = opt.get();
		profile.v2p(member);
		memberMapper.updateByPrimaryKey(member);
		return profile;
	}

	@RequestMapping(value = "/upload", method = RequestMethod.GET)
	public Token getUploadToken() {
		return new Token(storageService.getUploadImageToken());
	}

	@RequestMapping(value = "/suggest", method = RequestMethod.POST)
	public void suggest(@RequestParam String content) {
		System.out.println(content);
	}

	@RequestMapping(value = "/wallet", method = RequestMethod.GET)
	public Wallet getWalletDetail(HttpServletRequest request) throws SugarException {
		Integer uid = authService.getSubject(request);
		Optional<TuMember> opt = Optional.of(memberMapper.selectByPrimaryKey(uid));
		return new Wallet(opt.get().getBeans());
	}

	@RequestMapping("/orders")
	public Collection<Order> getOrders(HttpServletRequest request) throws SugarException {

		Integer uid = authService.getSubject(request);
		TfOrder cond = new TfOrder();
		cond.setMemberid(uid);
		return orderMapper.select(cond).stream().map(po -> Order.fromPo(po)).collect(Collectors.toList());
	}

	@RequestMapping("/messages")
	public Messages getMessages(HttpServletRequest request, @RequestParam long timestamp) throws SugarException {

		Integer uid = authService.getSubject(request);

		Long date = (timestamp >= 0 ? timestamp : System.currentTimeMillis());
		return new Messages(queryMessage(0, date), queryMessage(uid, date), System.currentTimeMillis());

	}

	private List<Messages.Message> queryMessage(Integer toid, Long timestamp) {

		Example example = new Example(TfMessage.class);
		example.createCriteria().andEqualTo("toid", toid).andGreaterThan("time", new Date(timestamp));
		return messageMapper.selectByExample(example).stream()
				.map(msg -> new Messages.Message(msg.getText(), msg.getTime().getTime(), msg.getId()))
				.collect(Collectors.toList());
	}

	@RequestMapping(value = "/password", method = RequestMethod.POST)
	public void setPassword(HttpServletRequest request, @RequestParam Long mobile, @RequestParam String password)
			throws SugarException {

		Integer uid = authService.getSubject(request);
		Optional<TuMember> found = Optional.of(memberMapper.selectByPrimaryKey(uid));
		if (belong(mobile, found.get())) {
			TuMember member = found.get();
			member.setPassword(CryptUtil.hash(password, Long.toString(member.getMobile())));
			memberMapper.updateByPrimaryKey(member);
		} else {
			throw new SugarException("mismatched mobile");
		}

	}

	@RequestMapping(value = "/mobile/check", method = RequestMethod.POST)
	public Result<Boolean> checkMobile(HttpServletRequest request, @RequestParam Long mobile,
			@RequestParam String passcode) throws SugarException {

		Integer uid = authService.getSubject(request);
		Optional<TuMember> found = Optional.of(memberMapper.selectByPrimaryKey(uid));

		Boolean result;
		if (belong(mobile, found.get()) && keyValueService.hasKey(Long.toString(mobile))
				&& keyValueService.get(Long.toString(mobile)).equals(passcode)) {
			result = true;
		} else {
			result = false;
		}

		return new Result<>(result);

	}

	private Boolean belong(Long mobile, TuMember member) {

		return mobile.equals(member.getMobile());
	}

}
